package com.pureut.order.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.StringUtils;
import com.pureut.common.core.utils.bean.BeanUtils;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.order.domain.ConverterManagement;
import com.pureut.order.domain.SubcontractingOrder;
import com.pureut.order.dto.ConverterManagementDto;
import com.pureut.order.dto.ConverterMqDto;
import com.pureut.order.export.ConverterManagementExport;
import com.pureut.order.export.ConverterManagementimportExport;
import com.pureut.order.mapper.ConverterManagementMapper;
import com.pureut.order.mapper.SubcontractingOrderMapper;
import com.pureut.order.service.ConverterManagementService;
import com.pureut.order.util.VariousMqUtil;
import com.pureut.order.vo.ConverterManagementVo;
import com.pureut.order.vo.OrderReviewVo;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.OrderFeignService;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.domain.SysUser;
import com.pureut.system.api.vo.SysAuditHistoryVo;
import com.pureut.system.api.vo.SysWorkbenchAuditAgentVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ConverterManagementServiceImpl extends ServiceImpl<ConverterManagementMapper, ConverterManagement> implements ConverterManagementService {

    @Resource
    ConverterManagementMapper converterManagementMapper;

    @Resource
    SubcontractingOrderMapper subcontractingOrderMapper;

    @Resource
    FeignService feignService;

    @Resource
    OrderFeignService orderFeignService;

    /**
     * 加工商列表
     *
     * @param converterManagementVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<ConverterManagementDto> getList(ConverterManagementVo converterManagementVo) {
        List<ConverterManagementDto> converterList = converterManagementMapper.getConverterList(converterManagementVo);
        //获取加工商状态缓存字典数据
        List<SysDictData> array = DictUtils.getDictCache("converter_status");
        Map<String, String> actualMap = array.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取加工商所属机构缓存字典数据
        List<SysDictData> organizationArray = DictUtils.getDictCache("converter_affiliated_organization");
        Map<String, String> organizationMap = organizationArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取加工商等级缓存字典数据
        List<SysDictData> levelArray = DictUtils.getDictCache("converter_level");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (ConverterManagementDto entity : converterList) {
            //获取加工商状态缓存字典数据
            entity.setAuditStatusDict(actualMap.get(entity.getAuditStatus()));
            //获取加工商所属机构缓存字典数据
//            entity.setAffiliatedOrganizationDict(organizationMap.get(entity.getAffiliatedOrganization()));
            //获取加工商等级缓存字典数据
            entity.setConverterLevelDict(levelMap.get(entity.getConverterLevel()));
            //归属人
//            entity.setAscriptionBy(feignService.getUserName(Long.valueOf(entity.getAscriptionBy())));
        }
        return converterList;
    }

    /**
     * 新增加工商
     *
     * @param converterManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addConverter(ConverterManagementVo converterManagementVo) throws Exception {
        //判断简称是否存在
        ConverterManagement converterManagementOne = getOne(new QueryWrapper<ConverterManagement>().lambda().eq(ConverterManagement::getConverterAbbreviation, converterManagementVo.getConverterAbbreviation()));
        if (converterManagementOne != null) {
            throw new GlobalException("该加工商简称已经存在");
        }
        ConverterManagement converterManagement = new ConverterManagement();
        converterManagement.setDeptId(SecurityUtils.getDeptId());
        converterManagement.setConverterName(converterManagementVo.getConverterName());
        converterManagement.setConverterAbbreviation(converterManagementVo.getConverterAbbreviation());
        String authorityCoding = feignService.getAuthorityCoding("order:subcontracting:converter:list");
        if (authorityCoding == null) {
            throw new GlobalException("未进行单据配置,单据编码生成失败");
        }
        converterManagement.setConverterNum(authorityCoding);
        converterManagement.setConverterLevel(Integer.parseInt(converterManagementVo.getConverterLevel()));
        converterManagement.setCreateBy(SecurityUtils.getUsername());
        converterManagement.setContactsBy(converterManagementVo.getContactsBy());
        converterManagement.setContactsInformation(converterManagementVo.getContactsInformation());
        converterManagement.setConverterAddress(converterManagementVo.getConverterAddress());
        converterManagement.setInvoicingInformation(converterManagementVo.getInvoicingInformation());
        converterManagement.setBusinessLicense(converterManagementVo.getBusinessLicense());
        converterManagement.setAuditStatus(1);
        converterManagement.setCreateTime(new Date());
        converterManagement.setRemark(converterManagementVo.getRemark());
        if (converterManagementVo.getAscriptionBy() != 0) {
            converterManagement.setAscriptionBy(converterManagementVo.getAscriptionBy());
        }

        //mq发送消息
        ConverterMqDto converterMqDto = new ConverterMqDto();
        BeanUtils.copyProperties(converterManagement, converterMqDto);
        VariousMqUtil.converterManagementMqSend(converterMqDto);
        return save(converterManagement);
    }

    /**
     * 冻结加工商
     *
     * @param id
     * @return
     */
    @Override
    public boolean frozenSupplier(Long id) {
        ConverterManagement converterManagement = getById(id);
        if (converterManagement.getAuditStatus() == 4) {
            converterManagement.setAuditStatus(6);
            return updateById(converterManagement);
        } else {
            throw new GlobalException("只能冻结启用的加工商");
        }
    }

    /**
     * 解冻加工商
     *
     * @param id
     * @return
     */
    @Override
    public boolean thawSupplier(Long id) {
        ConverterManagement converterManagement = getById(id);
        if (converterManagement.getAuditStatus() == 6) {
            converterManagement.setAuditStatus(4);
            return updateById(converterManagement);
        } else {
            throw new GlobalException("只能解冻冻结的加工商");
        }

    }

    /**
     * 撤销审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean revokeApproval(Long id) {
        ConverterManagement converterManagement = getById(id);
        if (converterManagement.getAuditStatus() == 2) {
            converterManagement.setAuditStatus(1);

            feignService.deleteDoc(converterManagement.getConverterNum(),"加工商管理");

            return updateById(converterManagement);
        } else {
            throw new GlobalException("只能撤销待审核的加工商");
        }

    }

    /**
     * 加工商信息导出
     *
     * @param converterManagementVo
     * @return
     */
    @Override
    public List<ConverterManagementExport> getInfoExport(ConverterManagementVo converterManagementVo) {
        List<ConverterManagementExport> exportList;
        //获取加工商状态缓存字典数据
        List<SysDictData> array = DictUtils.getDictCache("converter_status");
        Map<String, String> actualMap = array.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取加工商等级缓存字典数据
        List<SysDictData> levelArray = DictUtils.getDictCache("converter_level");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        if (converterManagementVo.getIdStr() == null) {
            exportList = converterManagementMapper.getExportList(converterManagementVo);
        } else {
            List<String> idList = Arrays.asList(converterManagementVo.getIdStr().split(","));
            exportList = converterManagementMapper.getDataByIdStr(idList);
        }
        for (ConverterManagementExport entity : exportList) {
            //状态
            entity.setAuditStatus(actualMap.get(entity.getAuditStatus()));
            //加工商等级
            entity.setConverterLevel(levelMap.get(entity.getConverterLevel()));
            //归属人
            if (entity.getAscriptionBy() != null) {
                String ascriptionBy = entity.getAscriptionBy();
                entity.setAscriptionBy(feignService.getUserName(Long.valueOf(ascriptionBy)));
            }
        }


        return exportList;
    }

    /**
     * 加工商信息导入
     *
     * @param coCustomer
     * @return
     */
    @Override
    public String importMouldData(List<ConverterManagementimportExport> coCustomer) {
        if (StringUtils.isNull(coCustomer) || coCustomer.size() == 0) {
            throw new GlobalException("导入加工商信息不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        //获取加工商等级缓存字典数据
        List<SysDictData> levelArray = DictUtils.getDictCache("converter_level");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (ConverterManagementimportExport mouldModelExport : coCustomer) {
            ConverterManagement converterManagement = new ConverterManagement();
            try {


                if (mouldModelExport.getConverterName() == null || mouldModelExport.getConverterAbbreviation() == null || mouldModelExport.getConverterLevel() == null) {
                    throw new GlobalException("存在必填字段为空，请核实");
                }

                //校验加工商简称是否为空
                boolean matches = mouldModelExport.getConverterAbbreviation().matches("[A-Z]{0,4}");
                if (!matches){
                    throw new GlobalException("加工商简称必须为4位大写字母");
                }

                //赋值
                converterManagement.setCreateBy(SecurityUtils.getUsername());
                converterManagement.setAuditStatus(1);
                //判断简称是否存在
                ConverterManagement converterManagementOne = getOne(new QueryWrapper<ConverterManagement>().lambda().eq(ConverterManagement::getConverterAbbreviation, mouldModelExport.getConverterAbbreviation()));
                if (converterManagementOne != null) {
                    throw new GlobalException("该加工商简称已经存在");
                }
                converterManagement.setConverterAbbreviation(mouldModelExport.getConverterAbbreviation());

                String authorityCoding = feignService.getAuthorityCoding("order:subcontracting:converter:list");
                if (authorityCoding == null) {
                    throw new GlobalException("未进行单据配置,单据编码生成失败");
                }
                converterManagement.setConverterNum(authorityCoding);
                //加工商名称
                converterManagement.setConverterName(mouldModelExport.getConverterName());
                //加工商等级
                for (Map.Entry<String, String> entry : levelMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getConverterLevel())) {
                        converterManagement.setConverterLevel(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }
                //判断归属人是否存在
                String userName = mouldModelExport.getAscriptionBy();
                if (userName != null) {
                    AjaxResult byUserName = feignService.getByUserName(userName);
                    if (byUserName == null) {
                        throw new GlobalException("未获取到相关归属人");
                    }
                    SysUser data = JSON.parseObject(JSON.toJSONString(byUserName.get("data")), SysUser.class);
                    converterManagement.setAscriptionBy(data.getUserId());
                }

                converterManagement.setContactsBy(mouldModelExport.getContactsBy());
                converterManagement.setConverterAddress(mouldModelExport.getConverterAddress());
                converterManagement.setContactsInformation(mouldModelExport.getContactsInformation());
                converterManagement.setRemark(mouldModelExport.getRemark());
                converterManagement.setCreateTime(new Date());
                converterManagement.setDeptId(SecurityUtils.getDeptId());

                this.save(converterManagement);

                //mq发送消息
                ConverterMqDto converterMqDto = new ConverterMqDto();
                BeanUtils.copyProperties(converterManagement, converterMqDto);
                VariousMqUtil.converterManagementMqSend(converterMqDto);

                successNum++;
                successMsg.append(successNum + "、加工商信息 " + mouldModelExport.getConverterName() + " 导入成功");

            } catch (Exception e) {
                failureNum++;
                String msg = failureNum + "、加工商 " + mouldModelExport.getConverterName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new GlobalException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }

        return successMsg.toString();
    }

    /**
     * 查看加工商
     *
     * @param id
     * @return
     */
    @Override
    public ConverterManagementDto getConverterById(Long id) {
        ConverterManagementDto converterManagementDto = new ConverterManagementDto();
        ConverterManagement converterManagement = getById(id);
        BeanUtils.copyProperties(converterManagement, converterManagementDto);
        //获取加工商所属机构缓存字典数据
        List<SysDictData> organizationArray = DictUtils.getDictCache("converter_affiliated_organization");
        Map<String, String> organizationMap = organizationArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
//        converterManagementDto.setAffiliatedOrganization(String.valueOf(converterManagement.getAffiliatedOrganization()));
//        converterManagementDto.setAffiliatedOrganizationDict(organizationMap.get(String.valueOf(converterManagement.getAffiliatedOrganization())));
        //获取加工商等级缓存字典数据order_supplier_level
        List<SysDictData> levelArray = DictUtils.getDictCache("converter_level");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        converterManagementDto.setConverterLevel(String.valueOf(converterManagement.getConverterLevel()));
        converterManagementDto.setConverterLevelDict(levelMap.get(String.valueOf(converterManagement.getConverterLevel())));
        //归属人
        if (converterManagement.getAscriptionBy() != 0) {
            Long userId = converterManagement.getAscriptionBy();
            String userName = feignService.getUserName(userId);
            converterManagementDto.setAscriptionBy(String.valueOf(userId));
            converterManagementDto.setAscriptionByDict(userName);
        }

        return converterManagementDto;
    }


    /**
     * 删除加工商
     *
     * @param ids
     * @return
     */
    @Override
    public boolean getDeleteByIds(String ids) throws SQLException {
        if (ids != null) {
            List<ConverterManagement> converterManagementList = new ArrayList<>();
            try {
                List<String> stringIds = Arrays.asList(ids.split(","));
                //获取加工商列表
                List<ConverterManagement> converterManagements = converterManagementMapper.selectBatchIds(stringIds);

                for (ConverterManagement entity : converterManagements) {
                    List<SubcontractingOrder> subcontractingOrder = subcontractingOrderMapper.selectList(new QueryWrapper<SubcontractingOrder>().lambda().eq(SubcontractingOrder::getConverterId, entity.getId()));
                    //如果没有关联数据，并且状态为已冻结，或者状态为待提交、未通过就放入删除列表
                    boolean delData = 6 == entity.getAuditStatus() && subcontractingOrder.size() == 0;
                    if (delData || entity.getAuditStatus() == 1 || entity.getAuditStatus() == 5) {
                        converterManagementList.add(entity);
                        feignService.deleteDoc(entity.getConverterNum(),"加工商管理");
                    } else {
                        throw new GlobalException("只能删除状态为待提交、未通过或者已冻结并且无关联的加工商");
                    }
                }

                if (converterManagementList.size() > 0) {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (ConverterManagement entity : converterManagementList) {
                        stringBuilder.append(entity.getConverterNum()).append(",");
                    }
                    StringBuilder stringBuilder1 = stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                    //mq同步删除加工商
                    ConverterMqDto converterMqDto = new ConverterMqDto();
                    converterMqDto.setConverterDeleteMark(11);
                    converterMqDto.setConverterNum(stringBuilder1.toString());
                    VariousMqUtil.converterManagementMqSendDelete(converterMqDto);



                    return removeByIds(converterManagementList);
                } else {
                    throw new SQLException("只能删除状态为待提交、未通过或者已冻结并且无关联的加工商");
                }
            } catch (Exception e) {
                throw new SQLException("只能删除状态为待提交、未通过或者已冻结并且无关联的加工商");
            }
        }
        return false;
    }

    /**
     * 提交审核
     */
    @Override
    public boolean reivewSubmit(Long id) {
        ConverterManagement converterManagement = getById(id);
        if (converterManagement.getAuditStatus() == 1) {
            converterManagement.setAuditStatus(2);

            SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();
            sysWorkbenchAuditAgentVo.setDocConfig("order:subcontracting:converter:converterReview");
            sysWorkbenchAuditAgentVo.setReceiptName("加工商管理");
            sysWorkbenchAuditAgentVo.setReceiptNumber(converterManagement.getConverterNum());//
            sysWorkbenchAuditAgentVo.setStatus(1);//待审核
            sysWorkbenchAuditAgentVo.setReceiptContent("有单据待审核,请及时审核");

            feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

            return updateById(converterManagement);
        } else {
            throw new GlobalException("只能操作待提交的加工商");
        }

    }

    /**
     * 修改加工商
     *
     * @param converterManagementVo
     * @return
     */
    @Override
    public boolean updateConverterById(ConverterManagementVo converterManagementVo) throws Exception {
        ConverterManagement converterManagement = getById(converterManagementVo.getId());
        if (converterManagement.getAuditStatus() == 1 || converterManagement.getAuditStatus() == 5) {
            List<ConverterManagement> list = list();
            List<ConverterManagement> collect = list.stream().filter(entity -> converterManagementVo.getId() != entity.getId()).collect(Collectors.toList());
            for (ConverterManagement entity : collect) {
                if (entity.getConverterAbbreviation().equals(converterManagementVo.getConverterAbbreviation())) {
                    throw new GlobalException("加工商简称已经存在");
                }
            }
            BeanUtils.copyProperties(converterManagementVo, converterManagement);
            converterManagement.setConverterLevel(Integer.parseInt(converterManagementVo.getConverterLevel()));
            converterManagement.setAscriptionBy(converterManagementVo.getAscriptionBy());

            if (converterManagement.getAuditStatus() == 5) {
                //调用审核
                SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
                String perms = "order:subcontracting:converter:converterReview";
                String auditDoc = converterManagement.getConverterNum();
                sysAuditHistoryVo.setAuditDoc(auditDoc);
                sysAuditHistoryVo.setPerms(perms);
                AjaxResult history = feignService.editHistory(sysAuditHistoryVo);
                String data = JSON.parseObject(JSON.toJSONString(history.get("msg")), String.class);
                if ("操作成功".equals(data)) {
                    converterManagement.setAuditStatus(1);
                    //mq发送消息
                    ConverterMqDto converterMqDto = new ConverterMqDto();
                    BeanUtils.copyProperties(converterManagement, converterMqDto);
                    VariousMqUtil.converterManagementMqSend(converterMqDto);

                    //修改审核代办状态为已处理
                    feignService.updateStatus(3,converterManagement.getConverterNum(),"加工商管理");//

                    return updateById(converterManagement);
                } else {
                    return false;
                }
            }
            //mq发送消息
            ConverterMqDto converterMqDto = new ConverterMqDto();
            BeanUtils.copyProperties(converterManagement, converterMqDto);
            VariousMqUtil.converterManagementMqSend(converterMqDto);
            return updateById(converterManagement);
        } else {
            throw new GlobalException("只能修改待提交和未通过的数据");
        }

    }

    /**
     * 加工商审核
     *
     * @param orderReviewVo
     * @return
     */
    @Override
    public boolean converterReview(OrderReviewVo orderReviewVo) {
        ConverterManagement converterManagement = getById(orderReviewVo.getId());
        if (converterManagement.getAuditStatus() == 2 || converterManagement.getAuditStatus() == 3) {
            String perms = "order:subcontracting:converter:converterReview";
            int isAdopt = orderReviewVo.getIsAdopt();
            String auditDoc = converterManagement.getConverterNum();
            String auditRemarks = orderReviewVo.getReviewComments();
            Long userId = SecurityUtils.getUserId();
            AjaxResult sequence = feignService.getSequenceTwo(perms, 2, isAdopt, auditRemarks, auditDoc, userId);
            Integer data = JSON.parseObject(JSON.toJSONString(sequence.get("data")), Integer.class);
            if (data == null) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (orderReviewVo.getIsAdopt() == 1) {
                if (data == 1) {
                    converterManagement.setAuditStatus(4);

                    feignService.updateStatus(3,converterManagement.getConverterNum(),"加工商管理");

                    return updateById(converterManagement);
                } else if (data == 2) {
                    converterManagement.setAuditStatus(3);
                    return updateById(converterManagement);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    converterManagement.setAuditStatus(5);

                    SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();
                    sysWorkbenchAuditAgentVo.setDocConfig("order:subcontracting:converter:converterReview");
                    sysWorkbenchAuditAgentVo.setReceiptName("加工商管理");
                    sysWorkbenchAuditAgentVo.setReceiptNumber(converterManagement.getConverterNum());//
                    sysWorkbenchAuditAgentVo.setStatus(2);//待处理

                    sysWorkbenchAuditAgentVo.setPassFlag("1");
                    sysWorkbenchAuditAgentVo.setCreateName(converterManagement.getCreateBy());
                    sysWorkbenchAuditAgentVo.setReceiptContent("有单据未通过,请及时查看");

                    feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

                    return updateById(converterManagement);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("只能对待审核和审核中的数据进行处理");
        }
    }
}
